home *** CD-ROM | disk | FTP | other *** search
- /*======================================================================================================
- TSP Solver (C) Copyright Fah-Chun Cheong (Work in Progress)
- ======================================================================================================*/
- #include <math.h>
- #include <sys/types.h>
- #include <stdio.h>
-
- #define BIGNUM 0x7fffffff
- #define N 400
- #define W(i,j) dist[i][j]
- #define swap(i,k,tmp) tmp = v[i]; v[i] = v[k]; v[k] = tmp
-
- typedef int Cost; /* type of intercity costs */
-
- Cost dist[N][N]; /* intercity costs matrix */
- Cost sum; /* cost of partial tour */
- Cost min; /* minimum cost so far */
-
- int best[N]; /* best tour so far */
- int v[N]; /* holds permutation of cities */
- int n; /* number of cities */
- int k; /* counting up partial tour */
-
- /*======================================================================================================
- Generate a random intercity matrix.
- ======================================================================================================*/
- void gen_map()
- {
- int i, j;
- int b, x = 197;
-
- for (i = 0; i < n; i++) /* go thru row */
- for (j = i+1; j < n; j++) { /* go thru column */
- x = (4757 * x + 1) % 32768;
- b = 1 + ((x / 16) % 256);
- W(i,j) = b; W(j,i) = b;
- }
- for (i = 0; i < n; i++) { /* go thru row */
- for (j = 0; j < n; j++) /* go thru column */
- printf("%8d", W(i,j)); /* print out cost */
- putchar('\n'); /* next line in matrix */
- }
- }
-
- /*======================================================================================================
- Dump out solution which is a tour thru all n cities.
- ======================================================================================================*/
- void print_tour()
- {
- int i;
-
- min = W(best[n-1], best[0]); /* policing ... */
- for (i = 0; i < n-1; i++)
- min = min + W(best[i], best[i+1]);
-
- printf("\n Best tour: ");
- for (i = 0; i < n; i++) {
- printf("%4d", best[i]);
- if ((i+1) % 20 == 0) printf("\n ");
- }
- printf("\n Min cost = ");
- for (i = 1; i < n; i++) {
- printf("%d + ", W(best[i-1], best[i]));
- if (i % 15 == 0) printf("\n ");
- }
- printf("%d = %d", W(best[n-1], best[0]), min); /* from last city to first city */
- printf("\n\n");
- }
-
- /*======================================================================================================
- Compute optimal tour by exhaustive branch-and-bound search.
- ======================================================================================================*/
- void search()
- {
- int tmp; /* temporary loc for swap */
- int i;
-
- if (k == n-1) { /* all cities visited ? */
- sum += W(v[n-1], v[0]); /* wrap around to form cycle */
- if (min > sum) { /* better than previous tour ? */
- min = sum; /* so update minimum cost so far */
- for (i = 0; i < n; i++)
- best[i] = v[i]; /* save the best solution so far */
- }
- sum -= W(v[n-1], v[0]); /* undo cycle */
- return; /* backtrack for more tours */
- }
- for (i = k+1; i < n; i++) /* try each remaining cities in turn */
- if (min > sum + W(v[k], v[i])) { /* branch only if opportunity is there */
- sum += W(v[k++],v[i]); /* add to partial sum of cost */
- swap(k, i, tmp); /* pick city i */
- search(); /* more cities ! */
- swap(i, k, tmp); /* unpick city i */
- sum -= W(v[--k],v[i]); /* deduct cost of edge to city i */
- }
- }
-
- /*======================================================================================================
- MAIN PROGRAM
- ======================================================================================================*/
- void main(argc, argv)
- int argc; /* how many arguments ? */
- char *argv[]; /* expect argv[1] to hold n */
- {
- int i, j;
-
- n = atoi(argv[1]); /* get number of cities */
- gen_map(); /* generate random matrix */
- for (k = 0; k < n; k++)
- v[k] = k; /* init cities */
- k = 0; /* start at city v[0] */
- sum = 0; /* zero cost to begin */
- min = BIGNUM; /* minimum over several solutions */
- search(); /* exhaustive search */
- print_tour();
- }
-
- /*======================================================================================================
- THE END
- ======================================================================================================*/
-